import random

from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.shortcuts import render

# Create your views here.
from rest_framework import mixins, viewsets, status, permissions, generics
from rest_framework.decorators import action
from rest_framework.exceptions import APIException
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin

from libs.yuntongxun.sms import CCP
from taotao import constant
from user.models import UserProfile, UserAddress
from user.serializers import UserSeriallizer, UserDetailSerializer, SmsSerializer, UserAdressSerializer
from user.utils import get_jwt_by_user, SMSRateThrottle, randusername, savetoken

User = get_user_model()


class UserViewset(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
    """
    使用用户名创建用户或登陆
    获取用户详细信息
    """
    serializer_class = UserSeriallizer
    queryset = UserProfile.objects.all()
    authentication_classes = []

    @action(detail=False, methods=['post'])
    def login(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)  # 获取序列化对象
        serializer.is_valid(raise_exception=True)  # 验证

        verifycode = serializer.validated_data['captcha_code']
        if verifycode.upper() != request.session.get('verifycode').upper():
            return Response({
                "status": 1,
                "message": "验证码错误"
            })

        username = serializer.validated_data['username'] # 获取用户名

        try:
            user = UserProfile.objects.get(username=username)  # 查询user是否已存在
            if user:  # 如果用户存在则登陆，返回token
                re_dict = serializer.data
                re_dict['token'] = get_jwt_by_user(user)
                re_dict['message'] = '登陆成功'
                savetoken(username, re_dict['token'])
                return Response(re_dict)
        except UserProfile.DoesNotExist:
            user = self.perform_create(serializer) # 注册
            re_dict = serializer.data
            re_dict['token'] = get_jwt_by_user(user)
            re_dict['message'] = '注册成功'
            savetoken(username, re_dict['token'])
            return Response(re_dict, status=status.HTTP_201_CREATED)

    def get_permissions(self):
        if self.action == "retrieve":
            return [permissions.IsAuthenticated()]
        elif self.action == "regorlogin":
            return []

        return []

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return UserDetailSerializer
        elif self.action == 'login':
            return UserSeriallizer

        return UserDetailSerializer

    def get_object(self):
        return self.request.user

    def perform_create(self, serializer):
        return serializer.save()

    def get_serializer_data(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        re_dict = serializer.data
        return serializer, re_dict


class SmsCodeViewset(viewsets.GenericViewSet):
    """
    手机登陆和注册
    """
    serializer_class = SmsSerializer
    throttle_class = SMSRateThrottle
    authentication_class = []

    def generate_code(self):
        """
        生成验证码
        """
        code = ''
        for i in range(4):
            code += str(random.randint(0, 9))

        return ''.join(code)

    @action(detail=False, methods=['get'])
    def get_smscode(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        # 验证合法
        serializer.is_valid(raise_exception=True)

        mobile = serializer.validated_data["mobile"]
        smscode = self.generate_code()  # 生成随机短信验证码

        # 将验证码保存在redis中
        mm = cache.set(mobile, smscode, constant.SMS_EXPIRE_TIME)
        # 发送验证码
        try:
            result = CCP().send_template_sms(mobile, [smscode, constant.SMS_EXPIRE_TIME // 60],
                                             constant.SMS_TEMPLATE_ID)
            if result == -1:
                return Response({
                    "status": 1,
                    "result": "短信发送失败"
                })
        except Exception as e:
            return Response({
                "status": 1,
                "result": "短信发送失败"
            })

        return Response({
            "status": 0,
            'mobile_code': smscode,
            "result": "短信发送成功"
        })

    @action(detail=False, methods=['post'])
    def mobile(self, request):
        """
        手机验证码注册或登陆
        """
        serializer = self.get_serializer(data=request.data)  # 获取序列化对象
        serializer.is_valid(raise_exception=True)  # 验证
        mobile = serializer.validated_data['mobile']
        realsmscode = cache.get(mobile)  # 获取redis缓存中的验证码
        smscode = request.data['smscode']

        print(smscode)

        re_dict = serializer.data
        if realsmscode:
            if realsmscode == smscode:  # 验证码正确
                try:
                    user = UserProfile.objects.get(mobile=mobile)
                    if user:  # 如果用户存在就登陆
                        re_dict['token'] = get_jwt_by_user(user)  # 获取token
                        headers = self.get_success_headers(serializer.data)
                        return Response(re_dict, headers=headers)
                except UserProfile.DoesNotExist:  # 用户不存在就注册
                    UserProfile.objects.create(mobile=mobile, username=randusername(), password=smscode)  # 注册
                    re_dict['token'] = get_jwt_by_user(user)
                    return Response(re_dict, headers=headers)
            else:
                return Response({
                    "result": "验证码错误"
                })
        else:
            return Response({
                "result": "验证码不存在"
            })


class UserAdressViewSet(mixins.RetrieveModelMixin,viewsets.GenericViewSet):
    queryset = UserAddress.objects.all()
    serializer_class = UserAdressSerializer
    lookup_field = 'user'

    @action(detail=True, methods=['get'])
    def default(self,request,user=None):
        """
        获取默认地址
        """
        queryset = self.get_queryset()
        user = UserProfile.objects.get(username=user)
        filter = {'user':user,'isdefault':'True'}
        default = get_object_or_404(queryset, **filter)
        serializer = UserAdressSerializer(default)
        return Response(serializer.data)


# class MultipleFieldLookupMixin(object):
#     """
#     Apply this mixin to any view or viewset to get multiple field filtering
#     based on a `lookup_fields` attribute, instead of the default single field filtering.
#     """
#     def get_object(self):
#         queryset = self.get_queryset()             # Get the base queryset
#         queryset = self.filter_queryset(queryset)  # Apply any filter backends
#         filter = {}
#         for field in self.lookup_fields:
#             if self.kwargs[field]: # Ignore empty fields.
#                 filter[field] = self.kwargs[field]
#         obj = get_object_or_404(queryset, **filter)  # Lookup the object
#         self.check_object_permissions(self.request, obj)
#         return obj

# class UserAdressViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
#     queryset = UserAddress.objects.all()
#     serializer_class = UserAdressSerializer
#     lookup_field = 'username'
#
#     def get_queryset(self):
#         username = self.request.query_params['username']
#         queryset = UserProfile.objects.filter(username=username)[0].address
#         if  'default' in self.request.query_params:
#             queryset = queryset.filter(isdefault=True)
#         return queryset




